#ifndef Algebra_EigenSolver_h
#define Algebra_EigenSolver_h

#include "AlgebraModule.h"
#include "AlgebraicTypes.h"
#include "ElapsedTimer.h"
#include "Object.h"

SG_NAMESPACE_OPEN
namespace Algebra
{
    /**
     * @brief Define interface of solvers for eigenvalue problems.
     *
     *  The generalized eigenproblem can be characterized as followings,
     * \f[
     *  \boldsymbol{\mathbf{A}}\boldsymbol{\mathbf{x}}=\lambda\boldsymbol{B} \boldsymbol{x}
     * \f]
     *
     * Strategy Factory Pattern is taken to Define a family of algorithms, encapsulate each one,
     * and make them interchangeable. Strategy lets the algorithm vary independently from clients
     * that use it.
     *
     * @see Erich Gamma. Design Patterns:elements of reusable object-oriented software. Addison Wesley, 1994.
     *
     * @author nene
     * @date February, 2025.
     */
    template <typename TDataType>
    class ALGEBRA_EXPORT TEigenSolver : public Base::Object
    {
    public:
        ///@name Type Definitions
        ///@{
        typedef /*typename*/ TDataType                 DataType;
        typedef /*typename*/ Matrix_t<TDataType>       MatrixType;
        typedef /*typename*/ SparseMatrix_t<TDataType> SparseMatrixType;
        typedef /*typename*/ Vector_t<TDataType>       VectorType;
        ///@}

        /**
         * The interface to solve the generalized eigenproblem described by SparseMatrices \p A and \p B.
         *
         * @param A SparseMatrix, the involving SparseMatrix.
         * @param B SparseMatrix, the involving SparseMatrix.
         * @param eigenvalues Array, the interested list of eigenvalues
         * @param eigenvectors Array, the interested list of eigenvectors
         */
        virtual void solve (const SparseMatrixType&  A,
                            const SparseMatrixType&  B,
                            std::vector<DataType>&   eigenvalues,
                            std::vector<VectorType>& eigenvectors) = 0;
    };

}  // namespace Algebra
SG_NAMESPACE_CLOSE

#endif  // Algebra_EigenSolver_h